package demo8;

import java.util.HashMap;

/**
 *
 */
public class Boolean_Evalution {
    public Boolean_Evalution2 createBoolean_Evalution2(){
        return new Boolean_Evalution2();
    }
    public class Boolean_Evalution2 {
        public void countEvalStartWithComputeNumberAndOper(String expression,boolean res) {
            int i = countEval(expression, res);
            System.out.println("count: "+i);
        }

        /**
         * left true + right true
         */
        public int countEval(String expression, boolean res) {
            char[] chars = expression.toCharArray();
            int length = chars.length;
            if(length==0){return 0;}
            if (length == 1) {
                return stringToBool(expression)==res?1:0;
            }
            int ways=0;
            for (int i = 1; i < length; i += 2) {
                // (1)^(0) | (0|0)
                // 1,3,5,
                // (1)^(0)|(0)|(1) no oper , contains completely
                String c = expression.substring(i, i + 1);
                String leftStr = expression.substring(0, i);
                String rightStr = expression.substring(i + 1);

                int leftTrue = countEval(leftStr, true);
                int leftFalse = countEval(leftStr, false);
                int rightTrue = countEval(rightStr, true);
                int rightFalse = countEval(rightStr, false);
                int total = (leftTrue+leftFalse) * (rightTrue+rightFalse);
                int qualified=0;
                if(c.equals("^")){
                    qualified+=leftTrue*rightFalse+leftFalse*rightTrue;
                }else if(c.equals("|")){
                    qualified+=leftTrue*rightTrue+leftTrue*rightFalse+leftFalse*rightTrue;
                }else if(c.equals("&")){
                    qualified+=leftTrue * rightTrue;
                }

                int subways = res?qualified:total -qualified;
                ways+=subways;
            }
            return ways;
        }

        public boolean stringToBool(String a) {
            return a.equals("1");
        }
    }
    public Boolean_Evalution3 createBoolean_Evalution3(){
        return new Boolean_Evalution3();
    }

    public class Boolean_Evalution3 {
        HashMap<String,Integer> map =new HashMap<>();
        public void countEvalStartWithComputeNumberAndOper(String expression,boolean res) {
            int i = countEval(expression, res);
            System.out.println("count: "+i);
        }

        /**
         * map compute the  count of expression;
         * left true + right true
         */
        public int countEval(String expression, boolean res) {
            // 0|0|1false
            if(map.containsKey(expression+res)){
                return map.get(expression+res);
            };

            char[] chars = expression.toCharArray();
            int length = chars.length;
            if(length==0){return 0;}
            if (length == 1) {
                return stringToBool(expression)==res?1:0;
            }
            int ways=0;
            for (int i = 1; i < length; i += 2) {
                // (1)^(0) | (0|0)
                // 1,3,5,
                // (1)^(0)|(0)|(1) no oper , contains completely
                String c = expression.substring(i, i + 1);
                String leftStr = expression.substring(0, i);
                String rightStr = expression.substring(i + 1);

                int leftTrue = countEval(leftStr, true);
                int leftFalse = countEval(leftStr, false);
                int rightTrue = countEval(rightStr, true);
                int rightFalse = countEval(rightStr, false);

                int total = (leftTrue+leftFalse) * (rightTrue+rightFalse);
                int qualified=0;
                if(c.equals("^")){
                    qualified+=leftTrue*rightFalse+leftFalse*rightTrue;
                }else if(c.equals("|")){
                    qualified+=leftTrue*rightTrue+leftTrue*rightFalse+leftFalse*rightTrue;
                }else if(c.equals("&")){
                    qualified+=leftTrue * rightTrue;
                }

                int subways = res?qualified:total -qualified;
                ways+=subways;
            }
            map.put(expression+res,ways);
            return ways;
        }

        public boolean stringToBool(String a) {
            return a.equals("1");
        }
    }

    /**
     * (1)^(0|0|1)
     * (1)^[](0)|(0)|(1)
     * 1^0|0|1
     * (1)^(0|0|1)
     * (1^0)|(0|1)
     * (1^0|0)|(1)
     * (1^0|0|1)
     * count--
     * move the () its index from (the first operator ) -> (the next operator ) -> (end) ,
     */
    int[] numbers = null;
    char[] operators = null;

    public void countEvalStartWithComputeNumberAndOper(String expression) {
        char[] chars = expression.toCharArray();
        int operator = (int) Math.floor(chars.length / 2);
        int number = operator + 1;
        numbers = new int[number];
        operators = new char[operator];
        int k = 0, m = 0;
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] == '^' || chars[i] == '&' || chars[i] == '|') {
                operators[m++] = chars[i];
            } else {
                numbers[k++] = chars[i];
            }
        }
        // init ,
        countEval(expression, "");
    }

    int count = 0;

    private void parseAndCompute(String str) {
        // how to 1+2=3

        char[] chars = str.toCharArray();
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] == '^') {

            } else if (chars[i] == '&') {

            } else if (chars[i] == '|') {

            } else if (chars[i] == '(') {

            } else if (chars[i] == ')') {

            } else {

            }
        }
    }

    /**
     * 1^0|0|1
     * (1)^(0|0|1)
     * (1)^(0|0|1)
     * (1)^(0)|(0|1)
     * expression:  create new expression every times
     * tmp: lastest created str,
     */
    public void countEval(String expression, String tmp) {
        char[] chars = expression.toCharArray();
        int length = chars.length;
        if (length == 1) {
            System.out.println(tmp + "(" + expression + ")");
            ;
            return;
        }
// 720 /(24 *6) =5
        for (int i = 1; i <= length; i += 2) {
            // (1)^(0) | (0|0)
            // 1,3,5,
            // (1)^(0)|(0)|(1) no oper , contains completely
            if (i == length) {
                System.out.println(tmp + "(" + expression + ")");
                ;
                continue;
            }
            String newTmp = new String(tmp + "(" + expression.substring(0, i) + ")" + expression.substring(i, i + 1));
            countEval(expression.substring(i + 1), newTmp);

        }

    }

    public boolean intToBool(int a) {
        return a == 1;
    }
}
